package org.springblade.modules.mes.opcua.constant;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springblade.core.tool.utils.SpringUtil;
import org.springblade.modules.mes.base.constant.PositionEnum;
import org.springblade.modules.mes.base.entity.*;
import org.springblade.modules.mes.base.service.*;
import org.springblade.modules.mes.opcua.config.OpcUaConfig;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class OpcUaCache {

	private static Map<String, Object> dataMap = new HashMap<>();

	public static void clear() {
		dataMap.clear();
	}

	private static IProduceStationService stationService;

	private static IProduceStationService getStationService() {
		if (stationService == null) {
			stationService = SpringUtil.getBean(IProduceStationService.class);
		}
		return stationService;
	}

	private static IProduceSiteService siteService;

	private static IProduceSiteService getSiteService() {
		if (siteService == null) {
			siteService = SpringUtil.getBean(IProduceSiteService.class);
		}
		return siteService;
	}

	private static IPrdInfoService prdInfoService;

	private static IPrdInfoService getPrdInfoService() {
		if (prdInfoService == null) {
			prdInfoService = SpringUtil.getBean(IPrdInfoService.class);
		}
		return prdInfoService;
	}


	private static IMaterialInfoService infoService;

	private static IMaterialInfoService getMaterialService() {
		if (infoService == null) {
			infoService = SpringUtil.getBean(IMaterialInfoService.class);
		}
		return infoService;
	}

	private static IPrdBomService bomService;

	private static IPrdBomService getBomService() {
		if (bomService == null) {
			bomService = SpringUtil.getBean(IPrdBomService.class);
		}
		return bomService;
	}

	private static IPrdBomStationService bomStationService;

	private static IPrdBomStationService getBomStationService() {
		if (bomStationService == null) {
			bomStationService = SpringUtil.getBean(IPrdBomStationService.class);
		}
		return bomStationService;
	}

	private static IPrdBomParamService prdBomParamService;

	private static IPrdBomParamService getBomParamService() {
		if (prdBomParamService == null) {
			prdBomParamService = SpringUtil.getBean(IPrdBomParamService.class);
		}
		return prdBomParamService;
	}

	private static final String STATION_SCOPE = "station.";

	private static final String SITE_SCOPE = "site.";

	private static final String PROD_SCOPE = "prod.";

	private static final String MAT_SCOPE = "mat.";

	private static final String MAT_ALL_SCOPE = "matAll.";

	private static final String BOM_SCOPE = "bom.";

	private static final String BOM_MAT_SCOPE = "bomMat.";

	private static final String BOM_STATION_ALL_SCOPE = "bomStationAll.";

	private static final String BOM_STATION_SCOPE = "bomStation.";

	private static final String BOM_PARAM_SCOPE = "bomParam.";

	/**
	 * 取得工序
	 *
	 * @param stationCode
	 * @return
	 */
	public static ProduceStation getByStationCode(String stationCode) {
		try {
			String key = STATION_SCOPE + stationCode;
			Object v = dataMap.get(key);
			if (v == null) {
				v = getStationService().getOne(new QueryWrapper<ProduceStation>()
					.lambda()
					.eq(ProduceStation::getStationCode, stationCode)
					.eq(ProduceStation::getIsDeleted, 0)
					.last("limit 1"));

				if (v != null) {
					dataMap.put(key, v);
				}
			}
			return (ProduceStation) v;
		} catch (Exception ex) {
			ex.printStackTrace();
			return null;
		}

	}

	/**
	 * 取得站位
	 *
	 * @param siteCode
	 * @return
	 */
	public static ProduceSite getBySiteCode(String siteCode) {
		try {
			String key = SITE_SCOPE + siteCode;
			Object v = dataMap.get(key);
			if (v == null) {
				v = getSiteService().getOne(new QueryWrapper<ProduceSite>()
					.lambda()
					.eq(ProduceSite::getSiteCode, siteCode)
					.eq(ProduceSite::getIsDeleted, 0)
					.last("limit 1"));

				if (v != null) {
					dataMap.put(key, v);
				}
			}
			return (ProduceSite) v;
		} catch (Exception ex) {
			ex.printStackTrace();
			return null;
		}

	}


	/**
	 * 取得产品，总成
	 *
	 * @param code
	 * @return
	 */
	public static PrdInfo getByProdCode(String code) {
		String key = PROD_SCOPE + code;
		Object v = dataMap.get(key);
		if (v == null) {
			v = getPrdInfoService().getOne(new QueryWrapper<PrdInfo>()
				.lambda()
				.eq(PrdInfo::getMaterialNo, code)
				.eq(PrdInfo::getMaterialFlag, "P")
				.eq(PrdInfo::getIsDeleted, 0)
				.last("limit 1"));

			if (v != null) {
				dataMap.put(key, v);
			}
		}
		return (PrdInfo) v;
	}


	/**
	 * 取得所有物料
	 *
	 * @return
	 */
	public static List<MaterialInfo> getAllMat() {
		String key = MAT_ALL_SCOPE + "0000";
		Object v = dataMap.get(key);
		if (v == null) {
			v = getMaterialService().list(new QueryWrapper<MaterialInfo>()
				.lambda()
				.eq(MaterialInfo::getMaterialFlag, "M")
				.eq(MaterialInfo::getIsDeleted, 0));

			if (v != null) {
				dataMap.put(key, v);
			}
		}
		return (List<MaterialInfo>) v;
	}

	/**
	 * 取得物料
	 *
	 * @param code
	 * @return
	 */
	public static MaterialInfo getByMatCode(String code) {
		String key = MAT_SCOPE + code;
		Object v = dataMap.get(key);
		if (v == null) {
			v = getMaterialService().getOne(new QueryWrapper<MaterialInfo>()
				.lambda()
				.eq(MaterialInfo::getMaterialNo, code)
				.eq(MaterialInfo::getMaterialFlag, "M")
				.eq(MaterialInfo::getIsDeleted, 0)
				.last("limit 1"));

			if (v != null) {
				dataMap.put(key, v);
			}
		}
		return (MaterialInfo) v;
	}

	/**
	 * 取得产品对应配方
	 *
	 * @param code
	 * @return
	 */
	public static PrdBom getBomByMatCode(String code) {
		String key = BOM_SCOPE + code;
		Object v = dataMap.get(key);
		if (v == null) {
			v = getBomService().getOne(new QueryWrapper<PrdBom>()
				.lambda()
				.eq(PrdBom::getMaterialNo, code)
				.eq(PrdBom::getIsDeleted, 0)
				.last("limit 1"));

			if (v != null) {
				dataMap.put(key, v);
			}
		}
		return (PrdBom) v;
	}

	/**
	 * 取得配方对应物料
	 *
	 * @param code
	 * @return
	 */
	public static List<PrdBom> getBomMatByProd(String code) {
		String key = BOM_MAT_SCOPE + code;
		Object v = dataMap.get(key);
		if (v == null) {
			v = getBomService().list(new QueryWrapper<PrdBom>()
				.lambda()
				.eq(PrdBom::getDirectLeaderNo, code)
				.eq(PrdBom::getIsDeleted, 0));

			if (v != null) {
				dataMap.put(key, v);
			}
		}
		return (List<PrdBom>) v;
	}


	/**
	 * 取得所有配方所哟工序
	 *
	 * @return
	 */
	public static Map<String, List<PrdBomStation>> getAllBomStation() {
		String key = BOM_STATION_ALL_SCOPE + "0000";
		Object v = dataMap.get(key);
		if (v == null) {
			List<PrdBomStation> dataList = getBomStationService().list(new QueryWrapper<PrdBomStation>()
				.lambda()
				.eq(PrdBomStation::getIsDeleted, 0)
				.orderByAsc(PrdBomStation::getSequence));

			if (dataList != null) {
				Map<String, List<PrdBomStation>> resMap = new HashMap<>();
				List<PrdBomStation> tempList;
				for (PrdBomStation prdBomStation : dataList) {
					tempList = resMap.get(prdBomStation.getProduceNo());
					if (tempList == null) {
						tempList = new ArrayList<>();
						resMap.put(prdBomStation.getProduceNo(), tempList);
					}
					tempList.add(prdBomStation);
				}
				v = resMap;
				dataMap.put(key, v);
			}
		}
		return (Map<String, List<PrdBomStation>>) v;
	}

	/**
	 * 取得指定配方的工序
	 *
	 * @param code
	 * @return
	 */
	public static List<PrdBomStation> getBomStationByProd(String code) {
		String key = BOM_STATION_SCOPE + code;
		Object v = dataMap.get(key);
		if (v == null) {
			v = getBomStationService().list(new QueryWrapper<PrdBomStation>()
				.lambda()
				.eq(PrdBomStation::getProduceNo, code)
				.eq(PrdBomStation::getIsDeleted, 0)
				.orderByAsc(PrdBomStation::getSequence));

			if (v != null) {
				dataMap.put(key, v);
			}
		}
		return (List<PrdBomStation>) v;
	}

	/**
	 * 取得指定配方的参数
	 *
	 * @param code
	 * @return
	 */
	public static List<PrdBomParam> getBomParamByProd(String code) {
		String key = BOM_PARAM_SCOPE + code;
		Object v = dataMap.get(key);
		if (v == null) {
			v = getBomParamService().list(new QueryWrapper<PrdBomParam>()
				.lambda()
				.eq(PrdBomParam::getProduceNo, code)
				.eq(PrdBomParam::getIsDeleted, 0));

			if (v != null) {
				dataMap.put(key, v);
			}
		}
		return (List<PrdBomParam>) v;
	}


	//监听参数
	private static List<String> subscriptionList = new ArrayList<>();

	/**
	 * 监听参数
	 *
	 * @return
	 */
	public static List<String> getSubscriptionKeys() {
		try {
			if (subscriptionList.size() == 0) {
				List<String> tags = new ArrayList<>();
				tags.add(OpcUaKey.archive);
				tags.add(OpcUaKey.scanStatus);
				for (PositionEnum pe : PositionEnum.values()) {
					if ("0".equals(pe.getIdx())) {
						tags.add(OpcUaKey.orderStatus);
						tags.add(OpcUaKey.paramStatus);
					} else {
						tags.add(OpcUaKey.orderStatus + "_" + pe.getIdx());
						tags.add(OpcUaKey.paramStatus + "_" + pe.getIdx());
					}

				}
				while (getSiteService() == null) {
					try {
						Thread.sleep(100);
					} catch (Exception ex) {

					}
				}
				List<ProduceSite> siteList = getSiteService().list(new QueryWrapper<ProduceSite>()
					.lambda()
					.eq(ProduceSite::getIsDeleted, 0));
				if (siteList != null) {
					siteList.forEach(site -> {
						tags.forEach(s -> {
							subscriptionList.add(OpcUaConfig.getInstance().group.concat(".").concat(site.getSiteCode()).concat(".").concat(s));
						});
					});
				}
			}
			return subscriptionList;
		} catch (Exception ex) {
			ex.printStackTrace();
			return null;
		}

	}

}
